package com.sdy.auth.api.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.sdy.common.model.BaseModel;
import com.sdy.common.model.BizException;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

/**
 * <p>
 * 系统资源表
 * </p>
 *
 * @author zzq
 * @since 2019-06-14
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class MenuDto extends BaseModel {
    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    private Integer id;

    /**
     * 父id
     */
    private Integer parentId;

    /**
     * 应用id
     */
    private Integer rootId;

    /**
     * 1-系统 2-菜单 3-请求
     */
    private Integer type;

    /**
     * 名称
     */
    private String name;

    /**
     * 路径
     */
    private String url;

    /**
     * 是否需要认证 1-是 2-否
     */
    private Integer authentication;

    /**
     * 是否需要权限 1-是 2-否
     */
    private Integer authorization;

    /**
     * 排序
     */
    private Integer sort;

    /**
     * 图标
     */
    private String icon;

    /**
     * 账号状态 1-正常 2-下线
     */
    private Integer state;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = DATETIME_FORMAT)
    private Date createTime;

    /**
     * 修改时间
     */
    @JsonFormat(pattern = DATETIME_FORMAT)
    private Date updateTime;

    /**
     * 该资源是否有授权 0-否 1-是
     */
    private Integer authed;

    private List<MenuDto> children;

    public List<MenuDto> toList() throws BizException {
        List<MenuDto> result = new ArrayList<>();
        Queue<MenuDto> queue = new LinkedList<>();
        queue.offer(this);
        MenuDto tmp;
        Set<Integer> idSet = new HashSet<>();
        int maxCnt = 1000;
        while ((tmp = queue.poll()) != null && --maxCnt > 0) {
            if (idSet.contains(tmp.getId())) {
                throw new BizException("资源间存在循环引用");
            }
            result.add(tmp);
            idSet.add(tmp.getId());
            List<MenuDto> children = tmp.getChildren();
            if (children != null) {
                children.forEach(queue::offer);
            }
        }
        return result;
    }
}
